🔷 Trimesh Tutorial

Master 3D Mesh Processing in Python

Introduction

Trimesh is a powerful Python library for loading, processing, and analyzing triangular meshes. It provides an extensive set of tools for working with 3D geometry, making it ideal for computer graphics, 3D printing, robotics, and scientific visualization.

💡 Key Features: Trimesh supports various file formats (STL, OBJ, PLY, GLTF), provides mesh analysis tools, boolean operations, ray tracing, and much more.

Installation

Install Trimesh using pip:

# Basic installation pip install trimesh # With additional dependencies for full functionality pip install trimesh[easy]

Getting Started

1. Loading a Mesh

import trimesh # Load a mesh from file mesh = trimesh.load_mesh('model.stl') # Or create a simple primitive sphere = trimesh.primitives.Sphere(radius=1.0) cube = trimesh.primitives.Box(extents=[2, 2, 2])

2. Basic Mesh Properties

# Access mesh properties print(f"Vertices: {len(mesh.vertices)}") print(f"Faces: {len(mesh.faces)}") print(f"Volume: {mesh.volume}") print(f"Surface Area: {mesh.area}") print(f"Center of Mass: {mesh.center_mass}") print(f"Bounding Box: {mesh.bounds}")

3. Mesh Visualization

# Show the mesh in a window mesh.show() # Or export as image scene = mesh.scene() png = scene.save_image(resolution=[1920, 1080])

Common Operations

Transformations

Translate, rotate, and scale meshes easily

Boolean Operations

Union, difference, and intersection of meshes

Mesh Repair

Fix holes, remove duplicates, and merge vertices

Ray Tracing

Cast rays and detect intersections

Transformations

import numpy as np # Translation mesh.apply_translation([1, 0, 0]) # Rotation (45 degrees around Z-axis) rotation_matrix = trimesh.transformations.rotation_matrix( np.radians(45), [0, 0, 1] ) mesh.apply_transform(rotation_matrix) # Scaling mesh.apply_scale(2.0) # Uniform scaling mesh.apply_scale([2, 1, 1]) # Non-uniform scaling

Boolean Operations

# Create two meshes sphere1 = trimesh.primitives.Sphere(radius=1.0) sphere2 = trimesh.primitives.Sphere(radius=0.8) sphere2.apply_translation([0.5, 0, 0]) # Union (combine meshes) union = sphere1.union(sphere2) # Difference (subtract one from another) difference = sphere1.difference(sphere2) # Intersection intersection = sphere1.intersection(sphere2)

Mesh Analysis

# Check if mesh is watertight (closed) print(f"Watertight: {mesh.is_watertight}") # Check if mesh is convex print(f"Convex: {mesh.is_convex}") # Get mesh quality metrics print(f"Euler Number: {mesh.euler_number}") # Find holes in the mesh holes = mesh.faces_sparse() # Calculate inertia tensor inertia = mesh.moment_inertia

Advanced Features

Ray Casting

# Cast rays at the mesh ray_origins = [[0, 0, -5]] ray_directions = [[0, 0, 1]] # Find intersection points locations, index_ray, index_tri = mesh.ray.intersects_location( ray_origins=ray_origins, ray_directions=ray_directions ) print(f"Intersection points: {locations}")

Mesh Slicing

# Slice mesh with a plane plane_origin = [0, 0, 0] plane_normal = [0, 0, 1] slice_2d = mesh.section( plane_origin=plane_origin, plane_normal=plane_normal ) # Get 2D path from slice if slice_2d is not None: path, to_3D = slice_2d.to_planar() path.show()

Convex Hull

# Create convex hull of point cloud or mesh convex_hull = mesh.convex_hull # Or from points directly points = np.random.random((100, 3)) hull = trimesh.convex.convex_hull(points)

Voxelization

# Convert mesh to voxel representation voxels = mesh.voxelized(pitch=0.1) # Convert voxels back to mesh voxel_mesh = voxels.as_boxes() voxel_mesh.show()

Practical Examples

Example 1: Create a Hollow Sphere

import trimesh # Create outer and inner spheres outer = trimesh.primitives.Sphere(radius=2.0) inner = trimesh.primitives.Sphere(radius=1.8) # Subtract inner from outer hollow_sphere = outer.difference(inner) # Save result hollow_sphere.export('hollow_sphere.stl') hollow_sphere.show()

Example 2: Mesh Repair and Cleanup

# Load potentially broken mesh mesh = trimesh.load('broken_model.stl') # Remove duplicate vertices mesh.merge_vertices() # Remove degenerate faces mesh.remove_degenerate_faces() # Fill holes mesh.fill_holes() # Fix normals mesh.fix_normals() print(f"Mesh is now watertight: {mesh.is_watertight}") mesh.export('repaired_model.stl')

Example 3: Point Cloud to Mesh

import numpy as np # Generate point cloud (e.g., from scanning) points = np.random.random((1000, 3)) * 10 # Create point cloud object cloud = trimesh.PointCloud(points) # Convert to mesh using convex hull mesh = cloud.convex_hull # Or use ball pivoting algorithm (requires additional setup) # mesh = trimesh.points.ball_pivot(points, radius=0.5) mesh.show()

Export Formats

Trimesh supports numerous file formats for import and export:

# Export to different formats mesh.export('output.stl') # STL format mesh.export('output.obj') # Wavefront OBJ mesh.export('output.ply') # PLY format mesh.export('output.off') # OFF format mesh.export('output.glb') # GLTF/GLB format # Export with specific settings mesh.export('output.stl', file_type='stl_ascii')
⚠️ Note: Some formats preserve more information than others. GLB/GLTF formats support colors and textures, while STL only stores geometry.

Tips and Best Practices

  • Always check if a mesh is watertight before performing boolean operations
  • Use mesh repair functions when loading meshes from external sources
  • For large meshes, consider simplification using mesh.simplify_quadric_decimation()
  • When working with multiple meshes, keep track of their coordinate systems
  • Use mesh.bounds to understand the spatial extent of your geometry
  • For better performance, consider using mesh caching: mesh.cache.clear() to manage memory